package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.*;
import com.itheima.domain.mongo.QuestionnaireLock;
import com.itheima.domain.mongo.SoulUserReport;
import com.itheima.service.db.QuestionnaireService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.QuestionnaireMongoService;
import com.itheima.vo.*;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
public class SoulTestManager {

    @Reference
    private QuestionnaireService questionnaireService;
    @Reference
    private QuestionnaireMongoService questionnaireMongoService;
    @Reference
    private UserInfoService userInfoService;


    public List<QuestionnaireVo> findQuestionnaire() {

        //1.获得登录用户id
        Long userId = UserHolder.get().getId();

        //2.查询用户是否用过测试灵魂模块
        SoulUserStatus soulUserStatus = questionnaireService.findUserStatus(userId);

        //3.查询不同等级测试题的初始信息
        List<Questionnaire> questionnaires = questionnaireService.findQuestionnaireAll();

        //4.判断用户使用过测灵魂模块么
        if (soulUserStatus == null) {
            //如果没查到这个用户，说明他第一次使用测灵魂模块，

            // 先向tb_soul_user_status插入信息
            /**
             *
             * tb_soul_user_status 只用来记录用户目前解锁到哪个等级的问卷
             *
             * */
            soulUserStatus = new SoulUserStatus();
            soulUserStatus.setUserId(userId);
            questionnaireService.insertUserStatus(soulUserStatus);

            //再向mongo中初始化用户与三张问卷的信息
            //上来先将三个测试卷设置给用户，并锁住
            for (Questionnaire questionnaire : questionnaires) {
                questionnaireMongoService.insertUserSatus(userId, questionnaire.getId());
            }
            questionnaireMongoService.unLock(userId, soulUserStatus.getLevel());//第一次进来初级问卷解锁
        } else {
            //查到这个用户了，说明不是第一次访问测灵魂模块

            //获取目前他处在什么等级的问卷（level）
            Integer level = soulUserStatus.getLevel();
            //处在1等级也就是初级问卷，给他解锁初级问卷(isLock = 0)
            questionnaireMongoService.unLock(userId, level);
        }

        //返回给前端的问卷list
        ArrayList<QuestionnaireVo> questionnaireVos = new ArrayList<>();
        // 5.查询问卷信息
        for (Questionnaire questionnaire : questionnaires) {
            QuestionnaireVo questionnaireVo = new QuestionnaireVo();
            //封装了 id name cover level start
            BeanUtil.copyProperties(questionnaire, questionnaireVo);

            //封装 isLock
            QuestionnaireLock questionnaireLock = questionnaireMongoService.findQuestionnaireLock(userId, questionnaire);
            questionnaireVo.setIsLock(questionnaireLock.getIsLock());


            //封装 reportId 根据userId和questionnaireId先去查有没有，有就返回，没有就是null
            SoulUserReport report = questionnaireMongoService.findReport(userId, questionnaire.getId().intValue());
            if (report != null) {
                questionnaireVo.setReportId(report.getId() + "");
            }

            //封装 List<SoulQuestionVo> questions
            List<SoulQuestion> soulQuestionList = questionnaireService.findQuestion(questionnaire.getId());
            //这个集合使用来给QuestionnaireListVo里的List<SoulQuestionVo> questions赋值
            List<SoulQuestionVo> questions = new ArrayList<>();

            //遍历数据库中的题目集
            for (SoulQuestion soulQuestion : soulQuestionList) {

                //创建一个前端需要的题目集实类,并赋值
                SoulQuestionVo soulQuestionVo = new SoulQuestionVo();
                soulQuestionVo.setId(soulQuestion.getId() + "");
                soulQuestionVo.setQuestion(soulQuestion.getQuestion());

                //setOptions()需要再去查询
                //从数据库查询答案集
                List<SoulQuestionOption> soulQuestionOptionList = questionnaireService.findOption(soulQuestion.getId());
                //前端的答案集
                List<SoulQuestionOptionVo> options = new ArrayList<>();
                //遍历封装答案集
                for (SoulQuestionOption soulQuestionOption : soulQuestionOptionList) {
                    SoulQuestionOptionVo option = new SoulQuestionOptionVo();
                    option.setId(soulQuestionOption.getId() + "");
                    option.setOption(soulQuestionOption.getContent());
                    //把答案(前端)封装到答案集(前端)
                    options.add(option);
                }
                soulQuestionVo.setOptions(options);

                //把题目(前端)封装到题目集(前端)
                questions.add(soulQuestionVo);
            }
            questionnaireVo.setQuestions(questions);
            questionnaireVos.add(questionnaireVo);
        }


        return questionnaireVos;
    }

    public String commitQuestionnaire(List<AnswerVo> answerList) {


        //获取当前用户id
        Long userId = UserHolder.get().getId();
        //初始得分(当前得分)
        Integer presentScore = 0;
        //初始四维属性
        Integer extroversion = 0;//外向
        Integer judgement = 0;//判断
        Integer abstraction = 0;//抽象
        Integer rationality = 0;//理性

        //存储选项信息(目的：封装维度)
        List<SoulQuestionOption> soulQuestionOptionList = new ArrayList<>();

        //遍历循环拿出每一个答案的id (optionId)
        for (AnswerVo answerVo : answerList) {

            String optionId = answerVo.getOptionId();
            //通过答案id 在tb_soul_question_option中 查询此答案得分 score
            SoulQuestionOption option = questionnaireService.findQuestionOption(optionId);

            soulQuestionOptionList.add(option);

            //更新当前分数
            Integer score = option.getScore();
            presentScore += score;

        }

        /**
         *
         *  根据不同问卷(questionnaire_id和score去查询对应的人格类型(一个文本内容 tb_ questionnaire_result表中的content字段)
         *  这里questionnaire_id根据 questionId 去 tb_question获取
         *
         * */
        AnswerVo answerVo = answerList.get(1);//随便取出一个问题id，都对应的同一个问卷
        String questionId = answerVo.getQuestionId();

        //通过问题id拿到了问题的详细信息
        SoulQuestion soulQuestion = questionnaireService.findQuestionById(questionId);
        //问卷id
        Integer questionnaireId = soulQuestion.getQuestionnaireId();

        //根据questionnaireId,presentScore去查 tb_ questionnaire_result表
        QuestionnaireResult questionnaireResult = questionnaireService.findResult(questionnaireId, presentScore);
        //人格类型
        String content = questionnaireResult.getContent();
        //封面(这里封面url存到mongoDB中，便于查看报告模块获取)
        String cover = questionnaireResult.getCover();

        //遍历选项集合，拿到四维值
        for (SoulQuestionOption soulQuestionOption : soulQuestionOptionList) {
             extroversion += soulQuestionOption.getExtroversion();
             judgement += soulQuestionOption.getJudgement();
             abstraction += soulQuestionOption.getAbstraction();
             rationality += soulQuestionOption.getRationality();
        }

        //封装个人报告内容
        SoulUserReport soulUserReport = new SoulUserReport();
        soulUserReport.setUserId(userId);
        soulUserReport.setConclusion(content);
        soulUserReport.setQuestionnaireId(questionnaireId.longValue());
        soulUserReport.setScore(presentScore);
        soulUserReport.setCover(cover);
        soulUserReport.setExtroversion(extroversion+"%");
        soulUserReport.setJudgement(judgement+"%");
        soulUserReport.setAbstraction(abstraction+"%");
        soulUserReport.setRationality(rationality+"%");


        /**
         *
         * 提交完某一等级问卷的报告之前，通过 userId 和 questionnaireId 去判断一下MongoDB中是否生成了该用户的报告
         * 如果没有该记录，那么做插入；如果有就做修改
         * */
        SoulUserReport report = questionnaireMongoService.findReport(userId, questionnaireId);

        if (report == null) {
            //未查询到此报告,进行插入保存
            report = questionnaireMongoService.saveReport(soulUserReport);
        } else {
            //查到了，进行更新
            ObjectId id = report.getId();
            soulUserReport.setId(id);
            questionnaireMongoService.saveReport(soulUserReport);
        }


        /**
         *
         * 提交完某一等级问卷的报告后，如果有下一等级问卷且未解锁，需进行解锁操作
         *
         * */
        //下一问卷等级 = 本次问卷等级 + 1
        //1.先查询目前用户在什么level(查询用户状态表 tb_soul_user_status),再去改变他的level
        SoulUserStatus userStatus = questionnaireService.findUserStatus(userId);
        //2.需要做个判断等级不能超过 问卷表中所有问卷的level最大值
        Integer level = userStatus.getLevel();
        Integer maxLevel = questionnaireService.findMaxLevel();


        if (level < maxLevel) {
            //只有当 当前处在的level小于最大level，才去做+1处理(也就是更新用户当前所处的问卷等级)
            Integer newLevel = level + 1;
            userStatus.setLevel(newLevel);
            questionnaireService.updateLevel(userStatus);
            //如果用户的level=maxLevel，说明他已经做完所有的问卷了，所以解锁下一张问卷的操作也在这个判断中做
            //先通过level查询问卷id
            Long id = questionnaireService.findQuestionnaireByLevel(newLevel);
            //在通过问卷id和userId去mongoDB中更改用户的锁状态
            questionnaireMongoService.updateLock(userId, id);
        }


        //报告id
        String userReportId = report.getId().toHexString();
        //返回个人报告id
        return userReportId;
    }

    public SoulResultVo findResult(String reportId) {
        //根据报告id查询报告
        SoulUserReport report = questionnaireMongoService.findReportById(reportId);


        //获取结论
        String conclusion = report.getConclusion();


        //获取cover
        String cover = report.getCover();

        //获取维度集List<DimensionVo>
        DimensionVo dimensionVo1 = new DimensionVo();
        dimensionVo1.setKey("外向");
        dimensionVo1.setValue(report.getExtroversion());

        DimensionVo dimensionVo2 = new DimensionVo();
        dimensionVo2.setKey("判断");
        dimensionVo2.setValue(report.getJudgement());


        DimensionVo dimensionVo3 = new DimensionVo();
        dimensionVo3.setKey("抽象");
        dimensionVo3.setValue(report.getAbstraction());

        DimensionVo dimensionVo4 = new DimensionVo();
        dimensionVo4.setKey("理性");
        dimensionVo4.setValue(report.getRationality());
        //封装List<DimensionVo>
        List<DimensionVo> dimensionVoList = new ArrayList<>();
        dimensionVoList.add(dimensionVo1);
        dimensionVoList.add(dimensionVo2);
        dimensionVoList.add(dimensionVo3);
        dimensionVoList.add(dimensionVo4);

        /**
         * 通过score和questionnaireId去查询相似用户（要求：分数相同，问卷id相同）
         * */
        //当前用户得分
        Integer score = report.getScore();
        //当前用户问卷id
        Long questionnaireId = report.getQuestionnaireId();
        //当前用户id
        Long userId = report.getUserId();
        //查询相似用户report(  相似判定方法：questionnaireId相同（即同一的等级的问卷），score 得分相同 )
        List<SoulUserReport> soulUserReports = questionnaireMongoService.findSimilarUser(score, questionnaireId, userId);
        //封装List<SimilarYouVo>
        List<SimilarYouVo> similarYouVoList = new ArrayList<>();
        for (SoulUserReport soulUserReport : soulUserReports) {
            //相似用户id
            Long uid = soulUserReport.getUserId();
            //封装相似用户的id和avar
            SimilarYouVo similarYouVo = new SimilarYouVo();
            UserInfo userInfo = userInfoService.findByUserId(uid);
            similarYouVo.setId(uid.intValue());
            similarYouVo.setAvatar(userInfo.getAvatar());
            similarYouVoList.add(similarYouVo);
        }


        //=================封装返回的SoulResultVo======================
        SoulResultVo soulResultVo = new SoulResultVo();
        soulResultVo.setConclusion(conclusion);
        soulResultVo.setCover(cover);
        soulResultVo.setDimensions(dimensionVoList);
        soulResultVo.setSimilarYou(similarYouVoList);

        return soulResultVo;
    }
}
